package com.niannian.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.niannian.db.DatabaseApi;
import android.content.Context;

public abstract class DBPreferBeanHelper extends PreferenceBeanHelper {
	protected DatabaseApi dbApi = null;
	protected String DatatableName = this.getClass().getSimpleName();
	protected Set<String> tablePrimary = new HashSet<String>();

	public void init(Context context) {
		super.init(context);
		dbApi = DatabaseApi.getDataBaseApi(context);
	}

	/** 获取对象对应数据库表名 */
	public String getDatatableName() {
		return DatatableName;
	}

	/** 设置对象对应数据库表名 */
	public void setDatatableName(String datatableName, String create) {
		if (create != null && !create.equals("")) {
			dbApi.open();
			dbApi.mDb.execSQL(create);
			dbApi.close();
		}
		DatatableName = datatableName;
	}

	/** 把所有的字段，更新到shareprefer和数据库中 */
	public void updateAll() throws Exception {
		updatePreferAll();
		Map<String, Object> setMap = new HashMap<String, Object>();
		Field[] fields = this.getClass().getDeclaredFields();
		for (Field field : fields) {
			if (!Modifier.isFinal(field.getModifiers()))
				setMap.put(field.getName(),
						FileUtils.getFieldValue(field, this));
		}
		updateDB(setMap, false);

	}

	/** 更新对象某属性，并把属性的修改更新到sharedprefer和数据库中 */
	public void update(String field, Object value) throws Exception {

		updatePrefer(field, value);
		Map<String, Object> setMap = new HashMap<String, Object>();
		setMap.put(field, value);
		updateDB(setMap, true);

	}

	/**
	 * 从数据库加载数据到对象。加载后，数据也会写入到对应的sharedpreferenced文件
	 * */
	public void loadFromDB(Map<String, Object> where) {
		try {

			String sql = "SELECT * FROM " + DatatableName + " WHERE "
					+ getPriWhereSQL(where);
			List all = dbApi.executeQuery(sql, this.getClass());
			if (all.size() > 0) {
				Common.copyto(all.get(0), this);
				updatePreferAll();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/** 添加主键 */
	public void addPrimaryKey(String key) {
		tablePrimary.add(key);
	}

	/** 删除主键 */
	public void remobePrimaryKey(String key) {
		tablePrimary.remove(key);
	}

	/**
	 * 将对象保存到数据库。 默认实现是，对象中的非final域都对应数据库字段保存进去。
	 * */
	/*
	 * protected void saveDB(){ Field[] fields =
	 * this.getClass().getDeclaredFields(); List<String> name=new
	 * LinkedList<String>(); List<String> values=new LinkedList<String>(); try{
	 * for(Field field:fields){ if (!Modifier.isFinal(field.getModifiers())){
	 * field.setAccessible(true); name.add(field.getName());
	 * values.add(FieldUtils.getFieldValue(field, this).toString()); } }
	 * dbApi.open();
	 * dbApi.mDb.execSQL("INSERT INTO "+DatatableName+" ("+Common.sImplode(name)
	 * +") VALUES ("+Common.sImplode(values)+")"); dbApi.close();
	 * }catch(Exception e){ e.printStackTrace(); }
	 * 
	 * 
	 * }
	 */

	/**
	 * 将对象中的数据存储到数据库中
	 * */
	/*
	 * protected void updateDB(Map<String,Object> setMap) throws Exception{
	 * String set=""; for(String key:setMap.keySet()){ if(!"".equals(set)){
	 * set+=" , "; } set+=(" "+key+"='"+setMap.get(key).toString()+"' "); }
	 * String
	 * sql="UPDATE "+DatatableName+" SET "+set+" WHERE "+getPriWhereSQL();
	 * dbApi.open(); dbApi.mDb.execSQL(sql); dbApi.close(); }
	 */

	protected void updateDB(Map<String, Object> setMap, boolean update)
			throws Exception {
		String sql = "";
		if (!update) {
			List<String> name = new LinkedList<String>();
			List<String> values = new LinkedList<String>();
			for (String key : setMap.keySet()) {
				Object value = setMap.get(key);
				name.add(key);
				values.add(value.toString());
			}

			for (String key : tablePrimary) {
				if (!setMap.keySet().contains(key)) {
					Field keyfield = this.getClass().getDeclaredField(key);
					keyfield.setAccessible(true);
					String value = FileUtils.getFieldValue(keyfield, this)
							.toString();
					name.add(key);
					values.add(value);
				}
			}
			sql = "REPLACE INTO " + DatatableName + " ("
					+ Common.sImplode(name) + ") VALUES ("
					+ Common.sImplode(values) + ")";
		} else {
			List<String> set = new LinkedList<String>();
			List<String> where = new LinkedList<String>();
			for (String key : setMap.keySet()) {
				String value = setMap.get(key).toString();
				set.add(key + "='" + Common.formatSqlValue(value) + "'");
			}
			for (String key : tablePrimary) {
				Field keyfield = this.getClass().getDeclaredField(key);
				keyfield.setAccessible(true);
				String value = FileUtils.getFieldValue(keyfield, this)
						.toString();
				where.add(key + "='" + value + "'");
			}
			sql = "UPDATE " + DatatableName + " SET "
					+ Common.implode(set, ",") + " WHERE "
					+ Common.implode(where, " AND ");
		}
		dbApi.open();
		dbApi.mDb.execSQL(sql);
		dbApi.close();
	}

	/*
	 * private String getPriWhereSQL() throws Exception{ String where="";
	 * for(String key:tablePrimary){ if(!"".equals(where)){ where+=" AND "; }
	 * Field keyfield=this.getClass().getDeclaredField(key);
	 * keyfield.setAccessible(true); String
	 * value=FieldUtils.getFieldValue(keyfield,this).toString();
	 * where+=(" "+key+"='"+value+"' "); } return where; }
	 */
	private String getPriWhereSQL(Map<String, Object> limit) throws Exception {
		String where = "";
		for (String key : limit.keySet()) {
			if (!"".equals(where)) {
				where += " AND ";
			}
			where += (" " + key + "='" + limit.get(key).toString() + "' ");
		}
		return where;
	}

}
